<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
	<head>
		<title>PSICQUIC View grapher</title>
		
		<!--The following three js files are used by Cytoscape Web-->
		<script type="text/javascript" src="js/cytoscape_web/json2.min.js"></script>
		<script type="text/javascript" src="js/cytoscape_web/AC_OETags.min.js"></script>
		<script type="text/javascript" src="js/cytoscape_web/cytoscapeweb.min.js"></script>
		<!--Load associative arrays specifying cell locations-->
		<script type="text/javascript" src="js/is_extracellular.min.js"></script>
		<script type="text/javascript" src="js/is_cell_wall.min.js"></script>
		<script type="text/javascript" src="js/is_outer_membrane.js"></script>
		<script type="text/javascript" src="js/is_periplasm.js"></script>
		<script type="text/javascript" src="js/is_plasma_membrane.min.js"></script>
		<script type="text/javascript" src="js/is_cytoplasm.min.js"></script>
		<script type="text/javascript" src="js/is_mitochondrion.min.js"></script>
		<script type="text/javascript" src="js/is_chloroplast.min.js"></script>
		<script type="text/javascript" src="js/is_nucleus.min.js"></script>

		<script type="text/javascript"><!--
			//Easy prototype chains in JavaScript
			if (typeof Object.create !== 'function') {
				Object.create = function(o) {
					var F = function(){};
					F.prototype = o;
					return new F();
				};
			};
			//Don't try to draw Cytoscape Web until the window has loaded.
			window.onload = function() {
				/*****Initialise variables start****/
				// id of Cytoscape Web container div
				var div_id = "cytoscapeweb",
				// Cytoscape initialization options
					options = {
						swfPath: "swf/CytoscapeWeb",
						flashInstallerPath: "swf/playerProductInstall"
					};
				//  This is a real example of a GraphML file from IntAct.
				//This will be removed when the files are merved with the production version.
				var networkXml = '\
						<?xml version="1.0" encoding="UTF-8"?>\
						<graphml xmlns="http://graphml.graphdrawing.org/xmlns"\
							xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\
							xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns\
								http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">\
								<key id="label" for="node" attr.name="label" attr.type="string"/>\
								<key id="identifier" for="node" attr.name="identifier" attr.type="string"/>\
								<key id="specie" for="node" attr.name="specie" attr.type="string"/>\
								<key id="type" for="node" attr.name="type" attr.type="string"/>\
								<key id="shape" for="node" attr.name="shape" attr.type="string">\
							<default>ELLIPSE</default>\
							</key>\
							<graph id="G" edgedefault="undirected">\
							  <node id="1">\
							    <data key="label">CNPY3</data>\
							    <data key="identifier">uniprotkb#Q9BT09</data>\
							    <data key="specie">Human</data>\
							    <data key="type">protein</data>\
							  </node>\
							  <node id="2">\
							    <data key="label">tig</data>\
							    <data key="identifier">uniprotkb#Q81LB8</data>\
							    <data key="specie">Bacillus anthracis</data>\
							    <data key="type">protein</data>\
							  </node>\
							  <edge source="1" target="2">\
							  </edge>\
							  <node id="3">\
							    <data key="label">TLR4</data>\
							    <data key="identifier">uniprotkb#O00206</data>\
							    <data key="specie">Human</data>\
							    <data key="type">protein</data>\
							  </node>\
							  <node id="4">\
							    <data key="label">EBI-1539279</data>\
							    <data key="identifier">intact#EBI-1539279</data>\
							    <data key="specie">Human</data>\
							    <data key="type">protein</data>\
							    </node>\
							  <edge source="3" target="4">\
							  </edge>\
							  <node id="5">\
							    <data key="label">PAUF</data>\
							    <data key="identifier">uniprotkb#C3PTT6</data>\
							    <data key="specie">Human</data>\
							    <data key="type">protein</data>\
							  </node>\
								<edge source="5" target="3">\
								</edge>\
								<node id="6">\
								   <data key="label">O76552</data>\
								   <data key="identifier">uniprotkb#O76552</data>\
								   <data key="specie">Filarial nematode worm</data>\
								   <data key="type">protein</data>\
								</node>\
								<edge source="6" target="3">\
								</edge>\
								<edge source="6" target="3">\
								</edge>\
								<edge source="6" target="3">\
								</edge>\
								<node id="7">\
								   <data key="label">Tlr4</data>\
								   <data key="identifier">uniprotkb#Q9QUK6</data>\
								   <data key="specie">Mouse</data>\
								   <data key="type">protein</data>\
								</node>\
								<edge source="7" target="5">\
								</edge>\
								<node id="8">\
								   <data key="label">LY96</data>\
								   <data key="identifier">uniprotkb#Q9Y6Y9</data>\
								   <data key="specie">Human</data>\
								   <data key="type">protein</data>\
								</node>\
								<edge source="8" target="3">\
								</edge>\
								<edge source="8" target="3">\
								</edge>\
								<edge source="8" target="3">\
								</edge>\
								<node id="9">\
								   <data key="label">TIRAP</data>\
								   <data key="identifier">uniprotkb#P58753</data>\
								   <data key="specie">Human</data>\
								   <data key="type">protein</data>\
								</node>\
								<edge source="3" target="9">\
								</edge>\
								<node id="10">\
								   <data key="label">alr1</data>\
								   <data key="identifier">uniprotkb#Q8ZJ10</data>\
								   <data key="specie">Yersinia pestis</data>\
								   <data key="type">protein</data>\
								</node>\
								<edge source="3" target="10">\
								</edge>\
							</graph>\
						</graphml>';
				var speciesHigherMulticellular = {
					"Human"		:true,
					"Mouse"		:true,
					"Rat"		:true,
					"Guinea pig":true,
					"Chicken"	:true,
					"Dog"		:true,
					"Cat"		:true,
					"Pig"		:true,
					"Bovine"	:true,
					"Sheep"		:true,
					"Hamster"	:true,
					"Cape hyrax":true
				};
				var speciesEukaryote = {
					'Filarial nematode worm': true,
					'apron ray': true
				};
				var speciesProkaryote = {
					"Escherichia coli"		:true,
					"Bacillus anthracis"	:true,
					"Yersinia pestis"		:true
				};
				//Colourblind schemes chosed from colorbrewer2.org
				var eukaryoteColor = [[],[],[],[],[],[],[]];
				//eukaryoteColor[0] is, of course, empty.
				eukaryoteColor[1] = [
					{ attrValue: 0, value: "#756BB1" }
				];
				eukaryoteColor[2] = [
					{ attrValue: 0, value: "#BCBDDC" },
					{ attrValue: 1, value: "#756BB1" }
				];
				eukaryoteColor[3] = [
					{ attrValue: 0, value: "#CBC9E2" },
					{ attrValue: 1, value: "#9E9AC8" },
					{ attrValue: 2, value: "#6A51A3" }
				];
				eukaryoteColor[4] = [
					{ attrValue: 0, value: "#CBC9E2" },
					{ attrValue: 1, value: "#9E9AC8" },
					{ attrValue: 2, value: "#756BB1" },
					{ attrValue: 3, value: "#54278F" }
				];
				eukaryoteColor[5] = [
					{ attrValue: 0, value: "#DADAEB" },
					{ attrValue: 1, value: "#BCBDDC" },
					{ attrValue: 2, value: "#9E9AC8" },
					{ attrValue: 3, value: "#756BB1" },
					{ attrValue: 4, value: "#54278F" }
				];
				eukaryoteColor[6] = [
					{ attrValue: 0, value: "#DADAEB" },
					{ attrValue: 1, value: "#BCBDDC" },
					{ attrValue: 2, value: "#9E9AC8" },
					{ attrValue: 3, value: "#807DBA" },
					{ attrValue: 4, value: "#6A51A3" },
					{ attrValue: 5, value: "#4A1486" }
				];
				var prokaryoteColor = [[],[],[],[],[],[]];
				prokaryoteColor[1] = [
					{ attrValue: 0, value: "#E6550D" }
				];
				prokaryoteColor[2] = [
					{ attrValue: 0, value: "#FDAE6B" },
					{ attrValue: 1, value: "#E6550D" }
				];
				prokaryoteColor[3] = [
					{ attrValue: 0, value: "#FDBE85" },
					{ attrValue: 1, value: "#FD8D3C" },
					{ attrValue: 2, value: "#D94701" }
				];
				prokaryoteColor[4] = [
					{ attrValue: 0, value: "#FDBE85" },
					{ attrValue: 1, value: "#FD8D3C" },
					{ attrValue: 2, value: "#E6550D" },
					{ attrValue: 3, value: "#A63603" }
				];
				prokaryoteColor[5] = [
					{ attrValue: 0, value: "#FDD0A2" },
					{ attrValue: 1, value: "#FDAE6B" },
					{ attrValue: 2, value: "#FD8D3C" },
					{ attrValue: 3, value: "#E6550D" },
					{ attrValue: 4, value: "#A63603" }
				];
				//This is the visual style Cytoscape uses
				var visual_style = {
					global: {
						backgroundColor: "#FFFFFF", //Default background is white.
						tooltipDelay: "500"
					},
					nodes: {
						color: {
									defaultValue:"#F5F5F5", //Light grey
									discreteMapper: {
										attrName:"type",
										entries:[
											{ attrValue:"protein",		value:"#FFFFFF"},
											{ attrValue:"compartment",	value:"#FDD0A2"},
											{ attrValue:"species",		value:"FDAE6B"}
										]
									}
								},
						labelHorizontalAnchor: "center",
						borderWidth: 0,
						size: 24
					},
					edges: {
						width: 1,
						color: "#000000"
					}
				};
				var forceDirectedLayout = {
					name:"ForceDirected",
					options:{gravitation:10}
				};
				var draw_options = {
					// Network data goes here
					network: networkXml,
					layout: forceDirectedLayout, //Default layout
					visualStyle: visual_style,
					edgesMerged: true
				};
				//AJAX object for communicating with UniProt BioMart server.
				var ajax = window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP");
				var noAjaxMessage = 'Unable to contact server to retrieve location data.\nUnable to show cellular location information.';
				//Finally, this creates the Cytoscape Web object called, vis.
				//Note that nothing is drawn until draw() is called.
				var vis = new org.cytoscapeweb.Visualization(div_id, options),
					first = true, //Flag if this is the first time the cytoscape object is being drawn
					networkJson = [];
				/*****Initialise variables end****/

				//This method is called only after Cytoscape Web has finished drawing.
				vis.ready( function() {
					//Debugging only.
					//We wnat to see how Cytoscape Web has translated the GraphML object.
					if (first) {
						//Get the network as a JavaScript object, but only do this once.
						networkJson = vis.networkModel();
						//Display the JavaScript object for debugging purposes.
						document.getElementById("GraphML").innerHTML = JSON.stringify(networkJson);
						first = false; //Only draw this the first time.
					};
					/////////////Sort nodes into compartments by species
					var buildSpeciesNetwork = function(n) {
						var species = {};
						var speciesList = [];
						var networkBySpecies = {"Species unknown":[]};
						for (var i=0; i < n.data.nodes.length; i++) {
							if (!n.data.nodes[i].specie) {
								//Node has no species
								networkBySpecies["Species unknown"].push(n.data.nodes[i]);
							} else {
								if (!species[n.data.nodes[i].specie]) {
									species[n.data.nodes[i].specie] = true;
									speciesList.push(n.data.nodes[i].specie);
									networkBySpecies[ n.data.nodes[i].specie ] = [];
								};
								//Slot node into right species compartment
								networkBySpecies[ n.data.nodes[i].specie ].push(n.data.nodes[i]);
							};
						};
						delete species;
						return {"speciesList":speciesList,"network":networkBySpecies}
					};
					var getUniprotID = function(node) {
						var idParts = node.identifier.split('#');
						if (idParts[0]==='uniprotkb') {
							return idParts[1];
						} else { return ''};
					};
					var removeEmptyCompartments = function(n2) {
						var n3 = { nodes:[] };
						for (i in n2.nodes) {
							if (!n2.nodes[i].network) {
								//Ordinary node
								n3.nodes.push(n2.nodes[i]);
							} else {
								//Compound node
								if (n2.nodes[i].network.nodes.length>0) {
									n3.nodes.push(n2.nodes[i]);
								};
							};
						};
						return n3;
					};
					var findLocationHigherMulticellular = function(uniprotID) {
						var domain = 'http://www.ebi.ac.uk/QuickGO/GAnnotation',
							query = 'format=tsv&aspect=C&protein=' + uniprotID;
						ajax.open("GET", domain + '?' + query, false);
						//cannot be asynchronous, otherwise you are in the next loop before you have got this info
						ajax.send();
						var goIds = ajax.responseText.match(/(GO:\d{7})/gm);
						if (goIds===null) { return null };
						for (j=0; j<goIds.length; j++) {
							if ( isExtracellular[goIds[j]] )	{ return 0 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isPlasmaMembrane[goIds[j] ])	{ return 1 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isNucleus[goIds[j]] )			{ return 4 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isMitochondrion[goIds[j]] )	{ return 3 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isCytoplasm[goIds[j]] )		{ return 2 };
						};
						return null; //Found nothing
					};
					var buildCompartmentNetworkHigherMulticellular = function(s, network) {
						var tempNetwork = { nodes:[] };
						var compartmentHigherMulticellular = {
							0:"Extracellular",
							1:"Plasma membrane",
							2:"Cytoplasm",
							3:"Mitochondrion",
							4:"Nucleus"
						};
						for (var j in compartmentHigherMulticellular) {
							tempNetwork.nodes[j] = {
								id: s + compartmentHigherMulticellular[j],
								label: compartmentHigherMulticellular[j],
								type: "compartment",
								network: { nodes:[] }
							};
						};
						for (var i=0; i < network.length; i++) {
							var uniprotID = getUniprotID(network[i]);
							if (uniprotID==='') {
								//Push node in at top level
								tempNetwork.nodes.push(network[i]);
							} else {
								var loc = findLocationHigherMulticellular(uniprotID);
								if (loc===null) {
									tempNetwork.nodes.push(network[i]);
								} else {
									tempNetwork.nodes[ loc ].network.nodes.push(network[i]);
								};
							};
						};
						//Remove empty compartments
						return removeEmptyCompartments(tempNetwork);
					};
					var findLocationEukaryote = function(uniprotID) {
						var domain = 'http://www.ebi.ac.uk/QuickGO/GAnnotation',
							query = 'format=tsv&aspect=C&protein=' + uniprotID;
						ajax.open("GET", domain + '?' + query, false);
						//cannot be asynchronous, otherwise you are in the next loop before you have got this info
						ajax.send();
						var goIds = ajax.responseText.match(/(GO:\d{7})/gm);
						if (goIds===null) { return null };
						for (j=0; j<goIds.length; j++) {
							if ( isCellWall[goIds[j]] )			{ return 1 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isExtracellular[goIds[j]] )	{ return 0 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isPlasmaMembrane[goIds[j] ])	{ return 2 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isNucleus[goIds[j]] )			{ return 6 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isMitochondrion[goIds[j]] )	{ return 4 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isChloroplast[goIds[j]] )		{ return 5 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isCytoplasm[goIds[j]] )		{ return 3 };
						};
						return null; //Found nothing
					};
					var buildCompartmentNetworkEukaryote = function(s, network) {
						var compartmentsEukaryote = {
							0:"Extracellular",
							1:"Cell wall",
							2:"Plasma membrane",
							3:"Cytoplasm",
							4:"Mitochondrion",
							5:"Chloroplast",
							6:"Nucleus"
						};
						for (j in compartmentsEukaryote.length) {
							cellular_compartment_network.nodes[j] = {
								id: s + compartmentsEukaryote[j],
								label: compartmentsEukaryote[j],
								type: "compartment",
								network: { nodes:[] }
							};
						};
						for ( i=0; i < network.length; i++ ) {
							var uniprotID = getUniprotID(network[i]);
							if (uniprotID==='') {
								//Push node in at top level
								tempNetwork.nodes.push(network[i]);
							} else {
								var loc = findLocationEukaryote(uniprotID);
								if (loc===null) {
									tempNetwork.nodes.push(network[i]);
								} else {
									tempNetwork.nodes[ loc ].network.nodes.push(network[i]);
								};
							};
						};
						//Remove empty compartments
						return removeEmptyCompartments(tempNetwork);
					};
					var findLocationProkaryote = function(uniprotID) {
						var domain = 'http://www.ebi.ac.uk/QuickGO/GAnnotation',
							query = 'format=tsv&aspect=C&protein=' + uniprotID;
						ajax.open("GET", domain + '?' + query, false);
						//cannot be asynchronous, otherwise you are in the next loop before you have got this info
						ajax.send();
						var goIds = ajax.responseText.match(/(GO:\d{7})/gm);
						if (goIds===null) { return null };
						for (j=0; j<goIds.length; j++) {
							if ( isCellWall[goIds[j]] )			{ return 1 };
						}
						for (j=0; j<goIds.length; j++) {
							if ( isExtracellular[goIds[j]] )	{ return 0 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isOuterMembrane[goIds[j]] )	{ return 2 };
						}
						for (j=0; j<goIds.length; j++) {
							if ( isPeriplasm[goIds[j]] )		{ return 3 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isPlasmaMembrane[goIds[j]] )	{ return 4 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isCytoplasm[goIds[j]] )		{ return 5 };
						};
						return null;
					};
					var buildCompartmentNetworkProkaryote = function(s, network) {
						var tempNetwork = { nodes:[] };
						//Load with cell compartments as clusters.
						var compartmentsProkaryote = {
							0:"Extracellular",
							1:"Cell wall",
							2:"Outer membrane",
							3:"Periplasmic space",
							4:"Inner membrane/Cell membrane",
							5:"Intracellular"
						};
						for (i in compartmentsProkaryote) {
							tempNetwork.nodes[i] = {
								id: s + compartmentsProkaryote[i],
								label: compartmentsProkaryote[i],
								type: "compartment",
								network: { nodes:[] }
							};
						};
						for ( var i=0; i < network.length; i++ ) {
							var uniprotID = getUniprotID(network[i]);
							if (uniprotID==='') {
								//Push node in at top level
								tempNetwork.nodes.push(network[i]);
							} else {
								var loc = findLocationProkaryote(uniprotID);
								if (loc===null) {
									tempNetwork.nodes.push(network[i]);
								} else {
									tempNetwork.nodes[ loc ].network.nodes.push(network[i]);
								};
							};
						};
						//Remove empty compartments
						return removeEmptyCompartments(tempNetwork);
					};
					var findLocationUnknownSpecies = function(uniprotID) {
						var domain = 'http://www.ebi.ac.uk/QuickGO/GAnnotation',
							query = 'format=tsv&aspect=C&protein=' + uniprotID;
						ajax.open("GET", domain + '?' + query, false);
						//cannot be asynchronous, otherwise you are in the next loop before you have got this info
						ajax.send();
						var goIds = ajax.responseText.match(/(GO:\d{7})/gm);
						if (goIds===null) { return null };
						for (j=0; j<goIds.length; j++) {
							if ( isNucleus[goIds[j]] )			{ return 8 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isChloroplast[goIds[j]] )		{ return 7 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isMitochondrion[goIds[j]] )	{ return 6 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isCellWall[goIds[j]] )			{ return 1 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isExtracellular[goIds[j]] )	{ return 0 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isOuterMembrane[goIds[j]] )	{ return 2 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isPeriplasm[goIds[j]] )		{ return 3 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isPlasmaMembrane[goIds[j]] )	{ return 4 };
						};
						for (j=0; j<goIds.length; j++) {
							if ( isCytoplasm[goIds[j]] )		{ return 5 };
						};
						return null;
					};
					var buildCompartmentNetworkUnknownSpecies = function(s, network) {
						var tempNetwork = { nodes:[] };
						//Load with cell compartments as compound nodes.
						var compartmentsUnknownSpecies = {
							0:"Extracellular",
							1:"Cell wall",
							2:"Outer membrane",
							3:"Periplasmic space",
							4:"Plasma membrane",
							5:"Cytoplasm",
							6:"Mitochondrion",
							7:"Chloroplast",
							8:"Nucleus"
						};
						for ( var i in compartmentsUnknownSpecies) {
							tempNetwork.nodes[i] = {
								id: s + compartmentsUnknownSpecies[i],
								label: compartmentsUnknownSpecies[i],
								type: "compartment",
								network:{ nodes:[] }
							};
						};
						for ( var i=0; i < network.length; i++ ) {
							var uniprotID = getUniprotID(network[i]);
							if (uniprotID==='') {
								//Push node in at top level
								tempNetwork.nodes.push(network[i]);
							} else {
								var loc = findLocationUnknownSpecies(uniprotID);
								if (loc===null) {
									tempNetwork.nodes.push(network[i]);
								} else {
									tempNetwork.nodes[ loc ].network.nodes.push(network[i]);
								};
							};
						};
						//Remove empty compartments
						return removeEmptyCompartments(tempNetwork);
					};
					//buildCompartmentNetwork should be called once only.
					var buildCompartmentNetwork = function() {
						//Create an empty component network model. Make it explicitly a global object
						window.component_network = { dataSchema:{}, data:{ nodes:[] } };
						//Copy in the dataSchema & the edges
						component_network.dataSchema = networkJson.dataSchema;
						component_network.data.edges = networkJson.data.edges;
						//The rest of the script deals only with the nodes
						//First sort by species, second by compartment
						window.m = buildSpeciesNetwork(networkJson);
						var speciesList = window.m.speciesList;
						var networkBySpecies = window.m.network;
						//Put the nodes with unknown species at the top level
						component_network.data.nodes = networkBySpecies["Species unknown"];
						//Now create compound nodes for each of the species
						for (var s=0; s<speciesList.length; s++) {
							var tempNetwork = {};
							if (!(!speciesHigherMulticellular[speciesList[s]])) {
								tempNetwork = buildCompartmentNetworkHigherMulticellular( s, networkBySpecies[speciesList[s]] );
							} else if (!(!speciesProkaryote)) {
								tempNetwork = buildCompartmentNetworkProkaryote( s, networkBySpecies[speciesList[s]] );
							} else if (!(!speciesEukaryote)) {
								tempNetwork = buildCompartmentNetworkEukaryote( s, networkBySpecies[speciesList[s]] );
							} else {
								tempNetwork = buildCompartmentNetworkUnknownSpecies( s, networkBySpecies[speciesList[s]] );
							};
							component_network.data.nodes.push(
								{
									id:speciesList[s],
									label:speciesList[s],
									type: "species",
									network:tempNetwork
								}
							);
						};
						//Print output for debugging purposes
						document.getElementById("compartmentNetwork").innerHTML = JSON.stringify(component_network);
					}
					var changeLayout = function() {
						document.getElementById("graphLayout").onclick = function() {
							if ( document.getElementById("layoutMerge").checked != vis.edgesMerged() ) {
								vis.edgesMerged(document.getElementById("layoutMerge").checked);
							};
							//Putting the nodes into compartments means changing the network 
							//layout forces us to use a completely different network. This
							//means we have to call draw() every time.
							if ( document.getElementById("layoutForceDirected").checked ) {
								document.getElementById("showStatus").innerHTML = "";
								if (layoutStatus!=1) {
									draw_options.visualStyle.nodes.color = "#F5F5F5";
									draw_options.network = networkXml;
									draw_options.layout = forceDirectedLayout;
									layoutStatus = 1;
									vis.draw(draw_options);
								};
							} else if ( document.getElementById("layoutCircle").checked ) {
								document.getElementById("showStatus").innerHTML = "";
								if (layoutStatus!=2) {
									draw_options.visualStyle.nodes.color = "#F5F5F5";
									draw_options.network = networkXml;
									draw_options.layout = "Circle";
									layoutStatus = 2;
									vis.draw(draw_options);
								};
							} else if ( document.getElementById("layoutRadial").checked ) {
								document.getElementById("showStatus").innerHTML = "";
								if (layoutStatus!=3) {
									draw_options.visualStyle.nodes.color = "#F5F5F5";
									draw_options.network = networkXml;
									draw_options.layout = "Radial";
									layoutStatus = 3;
									vis.draw(draw_options);
								};
							} else if ( document.getElementById("layoutCompartmentForceDirected").checked ) {
								if ( !window.component_network ) {
									document.getElementById("showStatus").innerHTML = "<em>Loading location data...<em>";
									buildCompartmentNetwork();
									document.getElementById("showStatus").innerHTML = "";
								};
								if (layoutStatus!=4) {
									//draw_options.visualStyle.nodes.color = color_mapper;
									draw_options.network = component_network; //change to component_network
									draw_options.layout = forceDirectedLayout;
									layoutStatus = 4;
									vis.draw(draw_options);//Must be the last command in the block
									//Everything after this point in the block is not executed!
								};
							} else if ( document.getElementById("layoutCompartmentCircle").checked ) {
								if ( !window.component_network ) {
									document.getElementById("showStatus").innerHTML = "<em>Loading location data...<em>";
									buildCompartmentNetwork();
									document.getElementById("showStatus").innerHTML = "";
								};
								if (layoutStatus!=5) {
									//draw_options.visualStyle.nodes.color = color_mapper;
									draw_options.network = component_network; //change to component_network
									draw_options.layout = "Circle";
									layoutStatus = 5;
									vis.draw(draw_options);//Must be the last command in the block
									//Everything after this point in the block is not executed!
								};
							} else if ( document.getElementById("layoutCompartmentRadial").checked ) {
								if ( !window.component_network ) {
									document.getElementById("showStatus").innerHTML = "<em>Loading location data...<em>";
									buildCompartmentNetwork();
									document.getElementById("showStatus").innerHTML = "";
								};
								if (layoutStatus!=6) {
									//draw_options.visualStyle.nodes.color = color_mapper;
									draw_options.network = component_network; //change to component_network
									draw_options.layout = "Radial";
									layoutStatus = 6;
									vis.draw(draw_options);//Must be the last command in the block
									//Everything after this point in the block is not executed!
								};
							};
						};
					};
					var saveGraph = function() {
						document.getElementById("saveAsPNG").onclick = function() { 
							vis.exportNetwork('png', 'export.php?type=image/png&ext=png');
						};
						document.getElementById("saveAsPDF").onclick = function() { 
							vis.exportNetwork('pdf', 'export.php?type=application/pdf&ext=pdf');
						};
						document.getElementById("saveAsSVG").onclick = function() { 
							vis.exportNetwork('svg', 'export.php?type=image/svg+xml&ext=svg');
						};
						document.getElementById("saveAsSIF").onclick = function() { 
							vis.exportNetwork('sif', 'export.php?type=text/plain&ext=sif');
						};
						document.getElementById("saveAsXGMML").onclick = function() { 
							vis.exportNetwork('xgmml', 'export.php?type=text/xml&ext=xgmml');
						};
						document.getElementById("saveAsGraphML").onclick = function() { 
							vis.exportNetwork('graphml', 'export.php?type=text/xml&ext=graphml');
						};
					};

					///////Listeners
					var handleNodeClick = function(event) {
						var nodeTarget = event.target;
						if (nodeTarget.shape!="RECTANGLE") {
							//document.getElementById("infoObjectType").innerHTML=JSON.stringify(nodeTarget);
							document.getElementById("infoObjectType").innerHTML='Node';
							document.getElementById("infoName").innerHTML=nodeTarget.data.label;
							document.getElementById("infoMoleculeType").innerHTML=nodeTarget.data.type;
							//If the identifier is Uniprot then insert a link to UniProtKB.
							var id = nodeTarget.data.identifier.split("#");
							if (id[0]=="uniprotkb") {
								document.getElementById("infoIdentifier").innerHTML = 'UniProt <a href="http://www.uniprot.org/uniprot/' + id[1] + '">' + id[1] + '</a>';
							} else if (id[0]=="chebi") {
								document.getElementById("infoIdentifier").innerHTML = 'ChEBI <a href="http://www.ebi.ac.uk/chebi/searchId.do?chebiId=' + id[1] + '">' + id[1] + '</a>';
							} else {
								document.getElementById("infoIdentifier").innerHTML = id[0] + " " + id[1];
							};
							var species = nodeTarget.data.specie;
							document.getElementById("infoSpecies").innerHTML=species?species:'<span style="color:grey;">no information</span>';
						} else {
							document.getElementById("infoObjectType").innerHTML="Compartment";
							document.getElementById("infoName").innerHTML=nodeTarget.data.label;
							document.getElementById("infoMoleculeType").innerHTML="";
							document.getElementById("infoIdentifier").innerHTML="";
							document.getElementById("infoSpecies").innerHTML="";
						};
					};
					var handleEdgeClick = function(event) {
						var edgeTarget = event.target;
						document.getElementById("infoObjectType").innerHTML='Edge';
						document.getElementById("infoIdentifier").innerHTML="";
						document.getElementById("infoName").innerHTML=edgeTarget.data.label?edgeTarget.data.label:"";
						document.getElementById("infoSpecies").innerHTML="";
					};
					vis.addListener( // add a listener for when nodes and edges are clicked
						"click", "nodes", 
						function(event) { (!event)?{}:handleNodeClick(event); }
					)
					.addListener(
						"click", "edges",
						function(event) { handleEdgeClick(event); }
					);
					changeLayout(); //check the layout box and change the layout
					saveGraph(); //check the save graph box and save as necessary
				});
				//Flag for current layout. No need to use this once preset layout is used, because the vis object
				//may then be queried directly.
				window.layoutStatus = 1;
				//Draw Cytoscape Web. The vis.ready will only be called after the network is drawn.
				vis.draw(draw_options);
			}; //end window.onload()
		//-->
		</script>

		<style>
			* { margin: 0; 
				padding: 0; 
				font-family: Helvetica, Verdana, Arial, sans-serif; 
			}
			html, 
			body { 
				height: 100%; 
				width: 100%; 
				padding: 0; 
				margin: 0; 
				background-color: white; 
				line-height: 1.5; 
				color: #000000; 
				font-size: 14px; 
			}
			/*The Cytoscape Web container must have its dimensions set.*/
			#cytoscapeweb { width: 50%;
							height: 50%;
							margin: 2%;
							border-style: solid;
							border-width: 2px;
			}
			#instructions { padding: 20px; }
			#rmargin {
					float: right;
					width: 40%;
					text-align: left;
			}
			#notes {
				width: 80%;
				height: 20%;
				padding: 10%
			}
			.form { width: 60%;
					text-align: left;
					margin: 2%;
					padding: 2%;
					border-style: outset;
					border-color: #0F0F0F; 
					border-width: 1px;
			}
			.formTitle { font-weight: bold; }
			.info { font-weight: bold;}
			.infoLabel { font-style: italic; }
			.saveFile { color:blue; text-decoration: underline; cursor: pointer; }
				#locExtracellular { background-color: #F7FCFD; }
				#locCellWall      { background-color: #E0ECF4; }
				#locOuterMembrane { background-color: #BFD3E6; } 
				#locPeriplasm     { background-color: #9EBCDA; }
				#locPlasmaMembrane{ background-color: #8C96C6; }
				#locCytoplasm     { background-color: #8C6BB1; }
				#locChloroplast   { background-color: #88419D; }
				#locMitochondrion { background-color: #810F7C; }
				#locNucleus       { background-color: #4D004B; }
			}
		</style>
	</head>

	<body>
		<h1 style="text-align: center;">PSIQUIC Viewer Mock-up</h1>
		<noscript style="color:red;">Sorry: this page only works with JavaScript.</noscript>
		<div id="rmargin">
			<form id="graphLayout" class="form">
				<div>
					<span class="formTitle">Layout</span><br />
					<input type="radio" name="layout" id="layoutForceDirected" checked="checked" />&nbsp;Force directed<br />
					<input type="radio" name="layout" id="layoutCircle" />&nbsp;Circle<br />
					<input type="radio" name="layout" id="layoutRadial" />&nbsp;Radial<br />
				</div>
				<div>
					<span class="formTitle">Compartmental</span><br />
					<input type="radio" name="layout" id="layoutCompartmentForceDirected" />&nbsp;Force directed<br />
					<input type="radio" name="layout" id="layoutCompartmentCircle" />&nbsp;Circle<br />
					<input type="radio" name="layout" id="layoutCompartmentRadial" />&nbsp;Radial<br />
				</div>
				<input type="checkbox" name="optionMerge" id="layoutMerge" checked="checked" />&nbsp;Merge edges<br />
				<span id="showStatus"></span>
			</form>
			<div class="form">
				<b>Click on a node</b> for more information.<br />
				<div style="width:65%; float:right; border:none;">
					<span id="infoObjectType" class="info"></span><br />
					<span id="infoName" class="info"></span><br />
					<span id="infoMoleculeType" class="info"></span><br />
					<span id="infoIdentifier" class="info"></span><br />
					<span id="infoSpecies" class="info"></span><br />
				</div>
				<div style="width:33%; border:none; text-align:right; margin-right:2%;">
					<span class="infoLabel">Object:</span><br />
					<span class="infoLabel">Name:</span><br />
					<span class="infoLabel">Molecule:</span><br />
					<span class="infoLabel">Identifier:</span><br />
					<span class="infoLabel">Species:</span>
				</div>
			</div>
			<div class="form">
				<span class="formTitle">Save as</span><br />
				<p>a picture:
				<span class="saveFile" id="saveAsPNG">png</span>
				<span class="saveFile" id="saveAsPDF">pdf</span>
				<span class="saveFile" id="saveAsSVG">svg</span></p>
				<p>a network:
				<span class="saveFile" id="saveAsGraphML">graphml</span>
				<span class="saveFile" id="saveAsSIF">sif</span>
				<span class="saveFile" id="saveAsXGMML">xgmml</span></p>
			</div>
			<!--
			<div class="form">
				<span class="formTitle">Compartment legend</span><br />
				<span id="locExtracellular">Extracellular</span><br />
				<span id="locCellWall">Cell Wall</span><br />
				<span id="locPeriplasm">Periplasm</span><br />
				<span id="locPlasmaMembrane">Plasma membrane or inner membrane</span>
				<span id="locCytoplasm">Cytoplasm</span><br />
				<span id="locChloroplast">Chloroplast</span><br />
				<span id="locMitochondrion">Mitochondrion</span><br />
				<span id="locNucleus">Nucleus</span><br />
			</div>
			-->
		</div>
		<div id="cytoscapeweb">
			If graph does not load, then please enable Flash on your browser.
		</div>
		<div id="instructions">
			This visualisation tool uses <a hef="http://cytoscapeweb.cytoscape.org/">Cytoscape Web</a>.
			<h2>Layouts</h2>
			<p>The first three layout (force directed, circle and radial) are ways of achieving
				aesthetically-pleasing arrangements of nodes that are easy to read. These layouts
				depend on network topology only. These layout contain no biological meaning, but are meant
				to be easy-to-read.</p>
			<ul>
				<li>In a <strong>force-directed layout</strong>, the nodes are modelled as being electrically charged
					(so they repel each other), but the edges are springs (pulling the nodes together).
					The starting positions for the nodes are random, so the layout will change every time.
					This produces layouts where the edges are of roughly uniform length, the nodes are
					arranged uniformly on the canvas, and the graph is symmetrical.</li>
				<li>In a <strong>circle layout</strong>, the nodes are arranged in a circle.</li>
				<li>In a <strong>radial layout</strong>, the nodes are arranged in concentric circles with the edges
					running radially from the centre of the circle to the outside.</li>
			</ul>
				<p>The fourth layout arranges the nodes (proteins) according to their intracellular location. 
				The intention is to give some biological meaning to the graph by arranging the nodes according 
				to their location in the cell. Not all proteins have been fully characterised and their location
				may not be known: these proteins will appear outside the labelled compartments.</p>
			<h2>Save options</h2>
			<p>If you want to save the network as an image for publication, we suggest that the best results
				are obtained using PDF format. The network formats (GraphML, SIF and XGMML) let you download
				the network to analyse using <a href="http://www.cytoscape.org/">Cytoscape</a>, <a href="http://gephi.org/">Gephi</a> or <a href="http://cran.r-project.org/web/packages/igraph/index.html">igraph</a> (<a href="http://www.r-project.org">R</a>).</p>
		</div>
		<div id="notes">
			<h1>Notes:</h1>
			<ol>
				<li>The current version uses an unversioned <a href="http://cytoscapeweb.cytoscape.org/">Cytoscape Web</a> (&gt;0.74) that supports compound nodes.
					This is just a mock-up and the graph is hard-coded into the page.</li>
				<li>The discrete color mapper does not appear to be working for the compound nodes, but is working for the simple nodes.
					The colour scheme is on the bottom right.</li>
				<li>The handler for edge attributes is there, but PSICQUIC does not currently include any edge attributes.</li>
				<li>The save function is now working.</li>
			</ol>
			<h2>Debugging</h2>
			<p>This is the GO:ID output:<br />
				<span id="goID"></span>
			</p>
			<p><strong>This is the serialized network JSON:</strong><br />
				<span id="GraphML"></span>
			</p>
			<p><strong>This is the network laid out in compartments:</strong><br />
				<span id="compartmentNetwork"></span>
			</p>
		</div>
	</body>
</html>
